# -*- coding: utf-8 -*-
from simpledcpp.core.base import DCPPPart, DCPPEvent, start_new_thread
import os, time,sys
class DownloadConnection(DCPPPart):
	
	def __init__(self, parent,condata):
		DCPPPart.__init__(self, parent)
		self.Events.Subscribe("DESTROY_CONNECTION",self._destroy)
		self.Events.Subscribe("REMOVE_TASK", self._removeTask)
		self._socket, self._n = condata
		self.direction = "Download"
		self._speed = 0

	def _removeTask(self, Event):
		try:
			if self._goal == Event.userdata[0]:
				self.stop()
		except:
			pass
	def _destroy(self, Event):
		if int(self.cid) == int(Event.userdata[0]):
			self.stop()
	def _preprocessing(self):
		try:
			self._processing()
		except:
			self.stop()

	def _processing(self):
		self._Work = 1
		while self._Work and self._socket.ok():
			self._goal = self.parent.getGoal(self._n)
			if self._goal == None:
				self.stop()
				return
			self.segment = self._goal.segment.require()
			if self.segment == None:
				self.stop()
				return
			if len(self._goal.TTH) < 39:
				prefix = ""
			else:
				prefix = "TTH/"
			length = self.segment[2] - self.segment[1]
			if length < 0:
				length = self.segment[2]
			self._socket.Send("$ADCGET file %s%s %s %s|"%(prefix,  self._goal.TTH, self.segment[1], length))
#			print "$ADCGET file %s%s %s %s|"%(prefix,  self._goal.TTH, segment[1], length)
			data = self._socket.Recieve(TIMEOUT = 20)
			if not self._socket.ok():
				self.parent.retGoal(self._n)
				self.stop()
				return
			data = data.split('|',1)
			prepare_buf = data[1]
			data = data[0].split(' ')
			dcount = 0
			if data[0] == "$ADCSND":
				self._fr = int(data[3])
				self._to = int(data[4])
				if int(self.segment[2]) == -1:
					self._goal.segment.update(self.segment[0], self._to)
				dcount = self._getFile(prepare_buf)
			else:
				#print data
				self.stop()
				return
			self._goal.segment.free(self.segment[0], dcount)
			self.parent.retGoal(self._n)
		self.stop()

	def _getFile(self, prepare_buf = ""):
		#print "FROM %s TO %s"%(self._fr, self._to)
		if prepare_buf == None:
			prepare_buf = ""
		if not os.path.isfile(self._goal.localfilename):
			try:
				filed = open(self._goal.localfilename,'w')
				filed.close()
			except:
				self.stop()
				return
		try:
			filed = open(self._goal.localfilename, "rw+")
		except:
			self.stop()
			return
		filed.seek(self._fr)
		download_count = len(prepare_buf)
		filed.write(prepare_buf)
		stime = time.time()
		scount = 0
		while self._socket.ok() and download_count < (self._to):
			buf = self._socket.Recieve(TIMEOUT = 20)#TIMEOUT = 20)
			if not self._socket.ok():
				break
			if buf != None and len(buf) > 0:
				filed.write(buf)
				download_count = download_count + len(buf)
			scount = scount + len(buf)
			if time.time() - stime < 1 and scount > int(self.settings.get("download_speed")):
				try:
					time.sleep(stime + 1 - time.time())
				except:
					pass
			if time.time() - stime > 1:
				stime = time.time()
				self._speed = scount
				scount = 0
				self.Event(DCPPEvent("ON_CONNECTION_UPDATE", (self.cid, self._speed, download_count, self._goal.localfilename,self._to,self._goal.TTH, self._n)))
		self.Event(DCPPEvent("ON_CONNECTION_UPDATE", (self.cid, self._speed, download_count, self._goal.localfilename,self._to,self._goal.TTH, self._n)))
		filed.close()
#		print "To: %s"%(download_count + int(self._fr))
		time.sleep(0.5)
		if download_count > self._to:
			download_count = self._to
		return download_count
	def start(self):
		self._thread = start_new_thread(self._preprocessing)

	def stop(self,*args, **kwargs):
		if self._Work == 0:
			return
		self._Work = 0
                self.Events.Unsubscribe("DESTROY_CONNECTION",self._destroy)
		self.Events.Unsubscribe("REMOVE_TASK", self._removeTask)
		try:
			self._thread.kill()
		except:
			pass
		try:
			self._socket.Close()
		except:
			pass
		try:
                        self._goal.segment.free(self.segment[0], 0)
                        self.parent.retGoal(self._n)
		except:
			pass
                self.Event(DCPPEvent("ON_DESTROY_CONNECTION",(self,)))
#		print "Destroyed."

